(一)JavaScript意外轉換的型別
自動轉型的例子:
10 + "object"; //轉換成全部都是字串 "10object"
"7" * "4"; //轉換成數字28
let n = 1 - "x"; //n==NaN 字串"x"無法被轉換成數字
n + "object"; //"NaNobject" NaN轉換為字串NaN
JavaScript型別轉換表:
值 | 轉為字串 | 轉為數字 | 轉為Boolean |
---|---|---|---|
undefined | "undefined" | NaN | false |
null | "null" | 0 | false |
true | "true" | 1 | |
false | "false" | 0 | |
" "(空字串) | 0 | false | |
"1.2" | 1.2 | true | |
"one" | NaN | true | |
0 | "0" | false | |
-0 | "0" | false | |
1(有限的,非零的) | "1" | true | |
Infinity | "Infinity" | true | |
-Infinity | "-Infinity" | true | |
NaN | "NaN" | false | |
{ } (任何物件) | 參閱3.9.3 | 參閱3.9.3 | true |
[] (空陣列) |
"" | 0 | true |
[9] (一個數值元素) |
"9" | 9 | true |
['a'] (任何其他陣列) |
使用join()方法 | NaN | true |
function(){} (任何函式) | 參閱3.9.3 | NaN | true |
(二)嚴格等於=== 以及 等於==
哪一個效能好?
使用JavaScript的等於符號時,應該都要用===
。因為使用不嚴格等於==
,會先進行轉型,再進行比較,而嚴格等於===
不會轉型,而是直接比較,所以===
效能較==
好。
null == undefined; //true 兩者視為相等 但轉換的意義是???? ===就是false
"0" == 0; //true "0"會在比較前,先轉換成數字
0 == false; //true Boolean會在比較前轉換為數字,而原本是數字就不會再轉型
"0" == false; //true "0"轉型成 0, false會轉型成 0 ,兩個都會轉型成 0
(三)可轉換性 (Convertibilty) 不代表兩個值相等
一個值對於另一個值的可轉換性 (Convertibilty) 並不代表那兩個值就是相等的。
若在一個預期Boolean 值得地方用了undefined,它就會被轉換成false,但這不代表undefined == false。
我們以if 條件式為例子:
// 在if的條件式內,ndefined轉換為false
if (undefined) {
console.log("是true就執行");
} else {
console.log("是false就執行");
}
//執行結果"是false就執行"
// 但undefined不等於false
console.log(undefined == false); // false
補充:因為if ..else是一個條件式,裡面的 (condition)放的值是需要轉換成true或是false的值。
if (condition)
statement1
// With an else clause
if (condition)
statement1
else
statement2
(四)如何使用明確的轉換 (explicit conversion),而不是讓JavaScript自己轉換型別?
Number("3"); //3
String(false); //"false"
Boolean([]); //true
(五)有哪些JavaScript「運算子」也可以用來作為明確的轉換(explicit conversion)?
+
+
轉型成字串:let x = 8; //原本x為數字
x + ""; //"8" 將x轉型為字串,等同於String(x)
使用 +
轉型為數字:
let x = "10"; //原本x為字串
+x; //10,等同於Number(x)
使用-
轉型為數字:
let y = "100";
y - 0; //100 轉型成數字
使用 !! 轉型成Boolean:
let z = 150;
!!z; //true 注意到使用兩個!!。如果只使用一個!就變成false()
(六)null 和undefined 以外的任何值,都有一個toString()方法,而這個方法通常都跟String()函式所回傳的相同。
const customObject = {
value: 42,
toString: function() {
return `The value is ${this.value}`;
}
};
// 使用toString()對象轉換為字串
const customString = customObject.toString();
console.log(customString); // 執行結果 "The value is 42"
// 使用String()將對象轉換為字串
const stringConversion = String(customObject);
console.log(stringConversion); // 執行結果 "The value is 42"
(七) JS 早期殘留物-包裹器物件 (wrapper)
注意:Boolean()、Number()、String()函式也可以作為Contructor以new來調用。若用這種方式來使用,會得到行為就像是原始的boolean、數字或字串的一個「包裹器 (wrapper)」物件。這是JS的歷史遺物,最好不要去使用他們。
舉例說明:
const strPrim = "foo"; // 原本就是字串
const strPrim2 = String(1); // 將1轉換成字串 "1"
const strPrim3 = String(true); // 將true轉匯成字串 "true"
const strObj = new String(strPrim);
// 使用new,會重新回傳wrapper object,型別就變object了!
console.log(typeof strPrim); // "string"
console.log(typeof strPrim2); // "string"
console.log(typeof strPrim3); // "string"
console.log(typeof strObj); // "object" 型別變成object,此為JS早期的殘留物
Reference
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String